﻿using AR.Drone.Infrastructure;
using AR.Drone.Data;
using FFmpeg.AutoGen;

namespace AR.Drone.Video
{
    public class VideoPacketDecoder : DisposableBase
    {
        private readonly PixelFormat _pixelFormat;
        private VideoConverter _videoConverter;
        private VideoDecoder _videoDecoder;
        private AVFrame _avFrame;
        private AVPacket _avPacket;

        public VideoPacketDecoder(PixelFormat pixelFormat)
        {
            _pixelFormat = pixelFormat;
            _avFrame = new AVFrame();
            _avPacket = new AVPacket();
        }

        private object _l = new object();
        public unsafe bool TryDecode(ref VideoPacket packet, out VideoFrame frame)
        {
            lock (_l)
            {

                if (_videoDecoder == null || _videoDecoder.CodecIdByte != packet.Codec) _videoDecoder = new VideoDecoder(packet.Codec);

                try
                {
                    fixed (byte* pData = &packet.Data[0])
                    {
                        _avPacket.data = pData;
                        _avPacket.size = packet.Data.Length;
                        if (_videoDecoder.TryDecode(ref _avPacket, ref _avFrame))
                        {
                            if (_videoConverter == null)
                                _videoConverter = new VideoConverter(_pixelFormat.ToAVPixelFormat());

                            byte[] data = _videoConverter.ConvertFrame(ref _avFrame);

                            frame = new VideoFrame();
                            frame.Timestamp = packet.Timestamp;
                            frame.Number = packet.FrameNumber;
                            frame.Width = packet.Width;
                            frame.Height = packet.Height;
                            frame.Depth = data.Length/(packet.Width*packet.Height);
                            frame.PixelFormat = _pixelFormat;
                            frame.Data = data;
                            return true;
                        }
                    }

                }
                catch
                {
                }
                frame = null;
                return false;
            }
        }


        protected override void DisposeOverride()
        {
            if (_videoDecoder != null) _videoDecoder.Dispose();
            if (_videoConverter != null) _videoConverter.Dispose();
        }
    }
}